<?php

namespace App\Helper;

use App\Contracts\LoggerInterface;
use App\Contracts\ResponseJsonInterface;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Context;
use Psr\Container\ContainerInterface;

/**
 * 响应格式化
 * Class ResponseJsonFormatter
 *
 * @method ResponseJsonInterface data($value)
 * @method ResponseJsonInterface message($value)
 * @method ResponseJsonInterface code($value)
 */
class ResponseJsonFormatter implements ResponseJsonInterface
{

    /**
     * @Inject()
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @Inject()
     * @var ResponseInterface
     */
    protected $response;

    public function setResponse($response)
    {
        $this->response = $response;
        return $this;
    }

    public function getResponse()
    {
        return $this->response;
    }

    public function __call($name, $value)
    {
        $value = array_pop($value);
        Context::override(static::class, function ($origin) use ($name, $value) {
            $origin = Arr::wrap($origin);
            return Arr::set($origin, $name, $value);
        });
        return $this;
    }

    private function getValue($name, $default)
    {
        return Arr::get(Context::get(static::class, []), $name, $default);
    }

    /**
     * 成功
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function success()
    {
        return $this->response->json([
            'data' => $this->getValue('data', null),
            'message' => $this->getValue('message', 'success'),
            'version' => $this->getValue('version', '1.0'),
            'code' => $this->getValue('code', 0),
        ])->withStatus(200);
    }

    /**
     * 失败
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function failed()
    {
        return $this->response->json([
            'data' => $this->getValue('data', null),
            'message' => $this->getValue('message', 'success'),
            'version' => $this->getValue('version', '1.0'),
            'code' => $this->getValue('code', 422),
        ])->withStatus(422);
    }

    /**
     * 错误
     * @param null|\Throwable $exception
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function error($exception = null)
    {
        if ($exception) {
            $this->container->get(LoggerInterface::class)->error($exception);
        }
        return $this->response->json([
            'data' => $this->getValue('data', null),
            'message' => $this->getValue('message', 'error'),
            'version' => $this->getValue('version', '1.0'),
            'code' => $this->getValue('code', 500),
        ])->withStatus(500);
    }
}